﻿#include "mytreeview.h"
#include <QAction>
#include <QDebug>
#include <QMessageBox>
#include <QInputDialog>
#include "user.h"
#include "company.h"

MyTreeView::MyTreeView(QWidget *parent) : QTreeView(parent)
{
    setHeaderHidden(true);                              //隐藏头部
    setSelectionBehavior(QTreeView::SelectRows);        //一次选中整行
    setSelectionMode(QTreeView::SingleSelection);       //单选，配合上面的整行就是一次选单行
    setContextMenuPolicy(Qt::CustomContextMenu);        //设置上下文菜单
    setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑

    setModel(&model);

    QAction *actionAdd = new QAction(QIcon(":/image/image/menu_add.png"), "添加类目", this);
    QAction *actionDelete = new QAction(QIcon(":/image/image/menu_delete.png"), "删除类目", this);
    QAction *actionEdit = new QAction(QIcon(":/image/image/menu_edit.png"), "编辑类目", this);

    menu.addAction(actionAdd);
    menu.addAction(actionDelete);
    menu.addAction(actionEdit);

    connect(this, &QTreeView::customContextMenuRequested, this, &MyTreeView::showMenu);

    connect(actionAdd, &QAction::triggered, this, &MyTreeView::addItem);
    connect(actionDelete, &QAction::triggered, this, &MyTreeView::deleteItem);
    connect(actionEdit, &QAction::triggered, this, &MyTreeView::editItem);

    connect(&companyService, &CompanyService::deleteOK,
            [=]()
    {
        MyTreeView::doDeleteItem();
    });

    connect(&companyService, &CompanyService::editOK,
            [=](QString newCategory)
    {
        MyTreeView::doEditItem(newCategory);
        this->updateCategory();
    });

    currentItem = rootItem;
}

/**
 * 显示右键菜单
 * @brief MyTreeView::showMenu
 * @param point
 */
void MyTreeView::showMenu(const QPoint point)
{
    if(User::getCompanyId().isEmpty()){
        //用户没有企业，不显示操作菜单
        return;
    }
    QModelIndex curIndex = indexAt(point);      //当前点击的元素的index
    QModelIndex index = curIndex.sibling(curIndex.row(),0); //该行的第1列元素的index
    if(index.isValid()){
        currentItem = model.itemFromIndex(index);
    }else{
        currentItem = rootItem;
    }
    menu.exec(mapToGlobal(point));
}

void MyTreeView::setCategoryType(Company::CategoryType categoryType)
{
    this->categoryType = categoryType;
}

/**
 * 检查treeItem节点下是否包含名称为label的节点
 * @brief MyTreeView::checkItem
 * @param treeItem
 * @param label
 * @return
 */
bool MyTreeView::checkItem(QStandardItem *treeItem, QString label){
    if(treeItem == nullptr){
        return false;
    }
    for(int i=0;i<treeItem->rowCount();i++){
        QStandardItem *child = treeItem->child(i);
        if(child->text() == label){
            QMessageBox::warning(this, "警告", "当前目录已存在相同节点！");
            return false;
        }
    }

    return true;
}

void MyTreeView::onAddActionTriggered()
{
    if(currentItem == rootItem->child(0)){
        //当前类目为所有类目
        QMessageBox::warning(this, "警告", "所有类目不能添加子项！");
        return;
    }
    if(currentItem!=rootItem && currentItem->parent()!=rootItem){
        //当前类目为二级类目
        QMessageBox::warning(this, "警告", "不能添加三级类目！");
        return;
    }

    if(categoryType == Company::FinanceCategory && currentItem==rootItem){
        QMessageBox::warning(this, "警告", "财务目录不能添加一级类目");
        return;
    }

    bool ok;
    QString text = QInputDialog::getText(this, "输入",
                                         "请输入添加类目", QLineEdit::Normal,
                                         "", &ok);

    if(ok){
        if(text.contains("#")){
            QMessageBox::warning(this, "警告", "类目名称不能含有#！");
        }else{
            if(checkItem(currentItem, text)){
                QStandardItem *addedItem = new QStandardItem(QIcon(":/image/image/类目.png"), text);
                currentItem->setIcon(QIcon(":/image/image/文件夹.png"));
                currentItem->appendRow(addedItem);
                updateCategory();
            }
        }
    }
}

/**
 * 添加菜单项
 * @brief MyTreeView::addItem
 */
void MyTreeView::addItem()
{
    onAddActionTriggered();
}

void MyTreeView::deleteItem()
{
    if(currentItem == rootItem){
        QMessageBox::warning(this, "警告", "不能删除根类别！");
        return;
    }

    if(currentItem == rootItem->child(0)){
        QMessageBox::warning(this, "警告", "不能删除所有类目！");
        return;
    }

    if(categoryType == Company::FinanceCategory && currentItem->parent() == rootItem){
        QMessageBox::warning(this, "警告", "财务类目不能删除一级类目！");
        return;
    }

    if(categoryType == Company::FinanceCategory &&
            (currentItem->parent() == rootItem->child(1) ||
             currentItem->parent() == rootItem->child(2)) &&
            currentItem == currentItem->parent()->child(0)){
        QMessageBox::warning(this, "警告", "财务目录不能删除所有收入和所有支出类目！");
        return;
    }

    QString message;
    if(currentItem->rowCount()!=0){
        message = "删除类别所有子类目将会同时删除！！！";
    }else{
        message = "确定删除当前类目？删除后不可撤销！！！";
    }

    if(userService.inputOperatePassword(this)){
        companyService.deleteCategory(
                    this,
                    categoryType,
                    selectedPrimaryDirectory(),
                    selectedSecondaryDirectory());
    }
}

void MyTreeView::doDeleteItem()
{
    QStandardItem *parent = currentItem->parent();
    parent->removeRow(currentItem->row());
    updateCategory();
}

void MyTreeView::editItem()
{
    if(currentItem == rootItem){
        QMessageBox::warning(this, "警告", "不能编辑根类别！");
        return;
    }

    if(currentItem == rootItem->child(0)){
        QMessageBox::warning(this, "警告", "不能编辑所有类目！");
        return;
    }

    if(categoryType == Company::FinanceCategory){
        if(currentItem->parent() == rootItem){
            QMessageBox::warning(this, "警告", "财务目录不能编辑一级类目！");
            return;
        }

        if(currentItem == currentItem->parent()->child(0)){
            QMessageBox::warning(this, "警告", "财务目录不能编辑所有收入和支二级类目！");
            return;
        }
    }

    if(userService.inputOperatePassword(this)){
        bool ok;
        QString newCategory = QInputDialog::getText(this, "输入",
                                            "请输入新的类目！", QLineEdit::Normal,
                                            "", &ok);
        if(ok){
            if(checkItem(currentItem->parent(), newCategory)){
                if(currentItem->parent() == rootItem){
                    //更新一级类目
                    companyService.updateCategory(
                                this,
                                categoryType,
                                selectedPrimaryDirectory(),
                                selectedSecondaryDirectory(),
                                newCategory,
                                "");
                }else{
                    companyService.updateCategory(
                                this,
                                categoryType,
                                selectedPrimaryDirectory(),
                                selectedSecondaryDirectory(),
                                "",
                                newCategory);
                }
            }
        }
    }
}

void MyTreeView::doEditItem(QString newCategory)
{
    currentItem->setText(newCategory);
}

QStandardItem* MyTreeView::selectedItem()
{
    QModelIndex index = currentIndex();
    QStandardItem *selectedItem = model.itemFromIndex(index);

    return selectedItem;
}

QString MyTreeView::selectedPrimaryDirectory()
{
    QStandardItem *selectedItem = this->selectedItem();

    if(selectedItem == nullptr){
        return "";
    }

    if(selectedItem == rootItem){
        return "";
    }

    if(selectedItem == rootItem->child(0)){
        return "";
    }

    if(selectedItem->parent() == rootItem){
        return selectedItem->text();
    }

    return selectedItem->parent()->text();
}

QString MyTreeView::selectedSecondaryDirectory()
{
    QStandardItem *selectedItem = this->selectedItem();

    if(selectedItem == nullptr){
        return "";
    }

    if(selectedItem == rootItem){
        return "";
    }

    if(selectedItem->parent() == rootItem){
        return "";
    }

    return selectedItem->text();
}

void MyTreeView::updateCategory()
{
    QString category = saveCategory(rootItem);

    switch (categoryType) {
    case Company::ProductCategory:
        Company::setProductCategory(category);
        break;
    case Company::ClientCategory:
        Company::setClientCategory(category);
        break;
    case  Company::GiverCategory:
        Company::setGiverCategory(category);
        break;
    case Company::FinanceCategory:
        Company::setFinanceCategory(category);
        break;
    }
    Company::setProductCategory(category);
    companyService.updateCategory(this, categoryType, category);
}

void MyTreeView::initWithCategory(QString category, QString rootName, QString firstCategoryName)
{
    model.clear();
    if(category.isEmpty()){
        QQueue<QVariant> queue;
        queue.enqueue(rootName);
        queue.enqueue(1);
        queue.enqueue(firstCategoryName);
        queue.enqueue(0);
        loadCategory(nullptr, rootItem, &queue);
    }else{
        QStringList categoryList = category.split("#");
        QQueue<QVariant> queue;
        for(QString curStr:categoryList){
            queue.enqueue(curStr);
        }

        loadCategory(nullptr, rootItem, &queue);
    }
}

void MyTreeView::initWithCategory(QString category, QString defaultCategory){
    model.clear();
    QStringList categoryList;
    if(category.isEmpty()){
        categoryList = defaultCategory.split("#");
    }else{
        categoryList = category.split("#");
    }

    QQueue<QVariant> queue;
    for(QString curStr:categoryList){
        queue.enqueue(curStr);
    }

    loadCategory(nullptr, rootItem, &queue);
}

void MyTreeView::loadCategory(QStandardItem *parent, QStandardItem *curItem, QQueue<QVariant> *categoryQueue)
{
    QString text = categoryQueue->dequeue().toString();
    int childSize = categoryQueue->dequeue().toInt();

    QIcon icon = QIcon(":/image/image/文件夹.png");
    if(childSize == 0){
        icon = QIcon(":/image/image/类目.png");
    }

    curItem = new QStandardItem(icon, text);
    if(parent == nullptr){
        rootItem = curItem;
        model.appendRow(rootItem);
    }else{
        parent->appendRow(curItem);
    }
    for(int i=0; i<childSize; i++)
    {
        loadCategory(curItem, nullptr, categoryQueue);
    }
}

QString MyTreeView::saveCategory(QStandardItem *curItem)
{
    QString category;
    category.append(curItem->text());
    category.append("#");
    category.append(QString("%1").arg(curItem->rowCount()));
    category.append("#");
    for(int i=0; i<curItem->rowCount(); i++)
    {
        QStandardItem *child = curItem->child(i);
        category.append(saveCategory(child));
    }

    return category;
}

QStringList MyTreeView::primaryDirectoryList()
{
    QStringList primaryDirectorys;

    for(int i=0; i<rootItem->rowCount(); i++){
        primaryDirectorys.append(rootItem->child(i)->text());
    }

    return primaryDirectorys;
}

QList<QStringList> MyTreeView::secondaryDirectoryList()
{
    QList<QStringList> secondaryDirectorys;

    for(int i=0; i<rootItem->rowCount(); i++){
        QStringList dirs;
        for(int j=0; j<rootItem->child(i)->rowCount(); j++){
            dirs.append(rootItem->child(i)->child(j)->text());
        }
        secondaryDirectorys.append(dirs);
    }

    return secondaryDirectorys;
}
